/**
 * 
 */
package cn.edu.cqu.bysj.wm.util;

import java.util.List;

import org.neo4j.graphdb.Node;

import cn.edu.cqu.bysj.wm.ago.anlys.Cluster;
import cn.edu.cqu.bysj.wm.ago.anlys.ModularityGN;
import cn.edu.cqu.bysj.wm.ago.anlys.ModularityLP;
import cn.edu.cqu.bysj.wm.ago.anlys.Similarity;
import cn.edu.cqu.bysj.wm.ago.anlys.Strength;
import cn.edu.cqu.bysj.wm.ago.gn.GN;
import cn.edu.cqu.bysj.wm.ago.gn.GNCommunity;
import cn.edu.cqu.bysj.wm.ago.lp.LP;
import cn.edu.cqu.bysj.wm.ago.lp.LPCommunity;
import cn.edu.cqu.bysj.wm.def.ConstDef;

/**
 * @author Meng
 * 
 */
public class CommunityOutput {
	public static StringBuilder printBuilder = new StringBuilder();

	public static void initPrintBuilder() {
		printBuilder = new StringBuilder();
	}

	public static void outputGN(GN gn) {

		// output base info and time
		String output1 = "-------------------------------------------info------------------------------------------------------------------------------------------\n";
		output1 += "data\t" + "node\t" + gn.n + "\tedge\t" + gn.e + "\t"
				+ gn.path + "\n";

		output1 += "-------------------------------------------time----------------------------------------------------------------------------------------------\n";
		long totalTime = gn.initTime + gn.iterTime;
		output1 += "time\ttotal\t" + totalTime + "\tinit\t" + gn.initTime
				+ "\titer\t" + gn.iterTime + "\tcalc betweenness\t" + gn.bTime
				+ "\n";

		// output communitys int the whole tree
		String output2 = "-------------------------------------------whole tree---------------------------------------------------------------------------------\n";
		for (long cid : GNCommunity.communitys.keySet()) {
			List<Node> list = GNCommunity.communitys.get(cid);
			int size = list.size();
			long pid = GNCommunity.hTree.getParent(cid);
			int level = GNCommunity.hTree.getLevel(cid);
			output2 += "cid\t" + cid + "\tsize\t" + size + "\tpid\t" + pid
					+ "\tlevel\t" + level + "\t";

			for (Node node : list) {
				long nid = node.getId();
				output2 += nid + " ";
			}
			output2 += "\n";
		}
		output2 += "-------------------------------------------total depth---------------------------------------------------------------------------------\n";
		output2 += "total depth\t" + GNCommunity.hTree.getDepth() + "\n";

		// output all pairs of depth and modularity
		String output3 = "-------------------------------------------depth vs Q-------------------------------------------------------------------------------------\n";
		for (int i : ModularityGN.Qs.keySet()) {

			double Q = DoubleFormat.doubleFormat(ModularityGN.Qs.get(i));
			int cn = ModularityGN.depthCommunity.get(i).size();

			output3 += "depth\t" + i + "\tQ\t" + Q + "\tcn\t" + cn + "\n";
		}

		// output max Q and depth

		String output4 = "-------------------------------------------max depth & Q------------------------------------------------------------------------------------------\n";
		int depth = ModularityGN.depth;
		double maxQ = ModularityGN.maxQ;
		output4 += "depth\t" + depth + "\tmaxQ\t" + maxQ + "\n";

		// output the best result
		String output5 = "-------------------------------------------best result--------------------------------------------------------------------------------\n";
		for (Node node : ModularityGN.depthCommunity.get(depth)) {

			long cid = node.getId();
			int size = GNCommunity.communitys.get(cid).size();
			double cc = DoubleFormat.doubleFormat(Cluster.clusterCoefficients
					.get(cid));
			output5 += "cid\t" + cid + "\tsize\t" + size + "\tcluster\t" + cc
					+ "\t";

			int stg = Strength.strengths.get(node.getId());

			String str = "";
			switch (stg) {
			case ConstDef.STRONG_COMMUNITY:
				str = "strong";
				break;
			case ConstDef.WEAK_COMMUNITY:
				str = "week";
				break;
			default:
				str = "neither";
				break;
			}
			output5 += str + "\t";

			List<Node> list = GNCommunity.communitys.get(node.getId());
			for (Node n : list) {
				output5 += n.getId() + " ";
			}
			output5 += "\n";
		}

		printBuilder.append(output1 + output2 + output3 + output4 + output5);

	}

	public static void outputLP(LP lp) {
		// output base info and time
		String output1 = "-------------------------------------------info------------------------------------------------------------------------------------------\n";
		output1 += "data\tnode\t" + lp.n + "\tedge\t" + lp.e + "\tpath\t"
				+ lp.path + "\n";

		output1 += "-------------------------------------------time------------------------------------------------------------------------------------------\n";
		long totalTime = lp.initTime + lp.iterTime;
		output1 += "time\ttotal\t" + totalTime + "\tinti\t" + lp.initTime
				+ "\titer\t" + lp.iterTime + "\n";

		// output communitys
		String output2 = "-------------------------------------------communitys----------------------------------------------------------------------------------------\n";
		for (long cid : LPCommunity.communitys.keySet()) {

			List<Node> list = LPCommunity.communitys.get(cid);
			int size = list.size();
			double cc = DoubleFormat.doubleFormat(Cluster.clusterCoefficients
					.get(cid));
			int stg = Strength.strengths.get(cid);

			output2 += "cid\t" + cid + "\tsize\t" + size + "\tcluster\t" + cc
					+ "\t";

			// ExportData.exportData(cid + "\t" + size+"\n",
			// ConstDef.OUTPUT_FILE);

			String str = "";
			switch (stg) {
			case ConstDef.STRONG_COMMUNITY:
				str = "strong";
				break;
			case ConstDef.WEAK_COMMUNITY:
				str = "week";
				break;
			default:
				str = "neither";
				break;
			}
			output2 += str + "\t";

			for (Node node : list) {
				long nid = node.getId();
				output2 += nid + " ";
			}
			output2 += "\n";
		}

		// output Q
		String output3 = "-------------------------------------------Q--------------------------------------------------------------------------------------\n";
		double Q = DoubleFormat.doubleFormat(ModularityLP.Q);
		output3 += "Q\t" + Q + "\tcn\t" + LPCommunity.communitys.size() + "\n";
		printBuilder.append(output1 + output2 + output3);

	}

	public static void outputSolutions() {
		// similarity of each solutions,Q
		String output1 = "-------------------------------------------solutions Q---------------------------------------------------------------------------------------------\n";
		for (Integer sid : Similarity.solutions.keySet()) {
			double Q = DoubleFormat.doubleFormat(Similarity.Qs.get(sid));
			int cn = Similarity.solutions.get(sid).size();
			output1 += "sid\t" + sid + "\tQ\t" + Q + "\tcn\t" + cn + "\n";
		}

		// similarity of each solutions,fsame and jaccard index
		String output2 = "-------------------------------------------jaccard index and fsame--------------------------------------------------------------------------------\n";
		output2 += Similarity.M.toString();
		printBuilder.append(output1 + output2);
	}

	public static void outputCSCN(int type) {
		// community size and number
		String output = "-------------------------------------------community size & number-------------------------------------------------------------------------------";
		if (type == ConstDef.LP) {
			for (int i : LPCommunity.cscn.keySet()) {
				output += "cs\t" + i + "\tcn\t" + LPCommunity.cscn.get(i)
						+ "\n";
			}
		} else {
			for (int i : GNCommunity.cscn.keySet()) {
				output += "cs\t" + i + "\tcn\t" + GNCommunity.cscn.get(i)
						+ "\n";
			}
		}
		printBuilder.append(output);
	}
}
